#include "qaudiorformat.h"
#include "sndfile.h"
#include <string>
#include <QString>

using namespace std;

namespace AudioUtils {

	class QAudioFormatPrivate
	{
	public:
		QAudioFormatPrivate()
		{
			init();
		}

		~QAudioFormatPrivate()
		{
		}

		void init()
		{
			path = "";
			memset(&sfinfo, 0, sizeof(SF_INFO));
		}

	public:
		QString path;
		SF_INFO sfinfo;
	};

	QAudioFormat::QAudioFormat()
		: p(new QAudioFormatPrivate)
	{
	}

	QAudioFormat::~QAudioFormat()
	{
		delete p;
	}

	bool QAudioFormat::open(const QString &path)
	{
		p->init();

		SF_INFO sfinfo;
		memset(&sfinfo, 0, sizeof(SF_INFO));

		auto filepath = path.toStdString();
		SNDFILE* sf = sf_open(filepath.c_str(), SFM_READ, &sfinfo);
		if (!sf)
		{
			return false;
		}

		if (!sf_format_check(&sfinfo))
		{
			sf_close(sf);
			return false;
		}

		p->path = path;
		p->sfinfo = sfinfo;
		sf_close(sf);
		return true;
	}

	QString QAudioFormat::path() const
	{
		return p->path;
	}

	quint64 QAudioFormat::samples() const
	{
		return p->sfinfo.frames;
	}

	int QAudioFormat::samplerate() const
	{
		return p->sfinfo.samplerate;
	}

	int QAudioFormat::channels() const
	{
		return p->sfinfo.channels;
	}

	bool QAudioFormat::mono() const
	{
		return p->sfinfo.channels == 1;
	}

	bool QAudioFormat::stereo() const
	{
		return p->sfinfo.channels > 1;
	}

	double QAudioFormat::totalTimeInSeconds() const
	{
		return (double)p->sfinfo.frames / p->sfinfo.samplerate;
	}

	quint32 QAudioFormat::totalTimeInMs() const
	{
		return static_cast<quint32>(totalTimeInSeconds() * 1000 + 0.5);
	}

}